<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Writing Validators - Zend Framework Manual</title>

    <link href="../css/shCore.css" rel="stylesheet" type="text/css" />
    <link href="../css/shThemeDefault.css" rel="stylesheet" type="text/css" />
    <link href="../css/styles.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Zend Framework</h1>
<h2>Programmer's Reference Guide</h2>
<ul>
    <li><a href="../en/zend.validate.writing_validators.html">Inglês (English)</a></li>
    <li><a href="../pt-br/zend.validate.writing_validators.html">Português Brasileiro (Brazilian Portuguese)</a></li>
</ul>
<table width="100%">
    <tr valign="top">
        <td width="85%">
            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="zend.validate.validator_chains.html">Validator Chains</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="zend.validate.html">Zend_Validate</a></span><br />
                        <span class="home"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="zend.validate.messages.html">Validation Messages</a></div>
                    </td>
                </tr>
            </table>
<hr />
<div id="zend.validate.writing_validators" class="section"><div class="info"><h1 class="title">Writing Validators</h1></div>
    

    <p class="para">
        <span class="classname">Zend_Validate</span> supplies a set of commonly needed validators, but
        inevitably, developers will wish to write custom validators for their particular needs. The
        task of writing a custom validator is described in this section.
    </p>

    <p class="para">
        <span class="classname">Zend_Validate_Interface</span> defines two methods,
         <span class="methodname">isValid()</span> and  <span class="methodname">getMessages()</span>, that may
        be implemented by user classes in order to create custom validation objects. An object that
        implements <span class="classname">Zend_Validate_Interface</span> interface may be added to a
        validator chain with  <span class="methodname">Zend_Validate::addValidator()</span>. Such objects
        may also be used with <a href="zend.filter.input.html" class="link"><span class="classname">Zend_Filter_Input</span></a>.
    </p>

    <p class="para">
        As you may already have inferred from the above description of
        <span class="classname">Zend_Validate_Interface</span>, validation classes provided with Zend
        Framework return a boolean value for whether or not a value validates successfully. They
        also provide information about <em class="emphasis">why</em> a value failed validation. The
        availability of the reasons for validation failures may be valuable to an application for
        various purposes, such as providing statistics for usability analysis.
    </p>

    <p class="para">
        Basic validation failure message functionality is implemented in
        <span class="classname">Zend_Validate_Abstract</span>. To include this functionality when creating a
        validation class, simply extend <span class="classname">Zend_Validate_Abstract</span>. In the
        extending class you would implement the  <span class="methodname">isValid()</span> method logic and
        define the message variables and message templates that correspond to the types of
        validation failures that can occur. If a value fails your validation tests, then
         <span class="methodname">isValid()</span> should return <b><tt>FALSE</tt></b>. If the value
        passes your validation tests, then  <span class="methodname">isValid()</span> should return
        <b><tt>TRUE</tt></b>.
    </p>

    <p class="para">
        In general, the  <span class="methodname">isValid()</span> method should not throw any exceptions,
        except where it is impossible to determine whether or not the input value is valid. A few
        examples of reasonable cases for throwing an exception might be if a file cannot be opened,
        an <acronym class="acronym">LDAP</acronym> server could not be contacted, or a database connection is
        unavailable, where such a thing may be required for validation success or failure to be
        determined.
    </p>

    <div class="example" id="zend.validate.writing_validators.example.simple"><div class="info"><p><b>Example #1 Creating a Simple Validation Class</b></p></div>
        

        <div class="example-contents"><p>
            The following example demonstrates how a very simple custom validator might be written.
            In this case the validation rules are simply that the input value must be a floating
            point value.
        </p></div>

        <pre class="programlisting brush: php">
class MyValid_Float extends Zend_Validate_Abstract
{
    const FLOAT = &#039;float&#039;;

    protected $_messageTemplates = array(
        self::FLOAT =&gt; &quot;&#039;%value%&#039; is not a floating point value&quot;
    );

    public function isValid($value)
    {
        $this-&gt;_setValue($value);

        if (!is_float($value)) {
            $this-&gt;_error();
            return false;
        }

        return true;
    }
}
</pre>


        <div class="example-contents"><p>
            The class defines a template for its single validation failure message, which includes
            the built-in magic parameter, <em class="emphasis">%value%</em>. The call to
             <span class="methodname">_setValue()</span> prepares the object to insert the tested value into
            the failure message automatically, should the value fail validation. The call to
             <span class="methodname">_error()</span> tracks a reason for validation failure. Since this
            class only defines one failure message, it is not necessary to provide
             <span class="methodname">_error()</span> with the name of the failure message template.
        </p></div>
    </div>

    <div class="example" id="zend.validate.writing_validators.example.conditions.dependent"><div class="info"><p><b>Example #2 Writing a Validation Class having Dependent Conditions</b></p></div>
        

        <div class="example-contents"><p>
            The following example demonstrates a more complex set of validation rules, where it is
            required that the input value be numeric and within the range of minimum and maximum
            boundary values. An input value would fail validation for exactly one of the following
            reasons:
        </p></div>

        <ul class="itemizedlist">
            <li class="listitem">
                <p class="para">The input value is not numeric.</p>
            </li>

            <li class="listitem">
                <p class="para">The input value is less than the minimum allowed value.</p>
            </li>

            <li class="listitem">
                <p class="para">The input value is more than the maximum allowed value.</p>
            </li>
        </ul>

        <div class="example-contents"><p>
            These validation failure reasons are then translated to definitions in the class:
        </p></div>

        <pre class="programlisting brush: php">
class MyValid_NumericBetween extends Zend_Validate_Abstract
{
    const MSG_NUMERIC = &#039;msgNumeric&#039;;
    const MSG_MINIMUM = &#039;msgMinimum&#039;;
    const MSG_MAXIMUM = &#039;msgMaximum&#039;;

    public $minimum = 0;
    public $maximum = 100;

    protected $_messageVariables = array(
        &#039;min&#039; =&gt; &#039;minimum&#039;,
        &#039;max&#039; =&gt; &#039;maximum&#039;
    );

    protected $_messageTemplates = array(
        self::MSG_NUMERIC =&gt; &quot;&#039;%value%&#039; is not numeric&quot;,
        self::MSG_MINIMUM =&gt; &quot;&#039;%value%&#039; must be at least &#039;%min%&#039;&quot;,
        self::MSG_MAXIMUM =&gt; &quot;&#039;%value%&#039; must be no more than &#039;%max%&#039;&quot;
    );

    public function isValid($value)
    {
        $this-&gt;_setValue($value);

        if (!is_numeric($value)) {
            $this-&gt;_error(self::MSG_NUMERIC);
            return false;
        }

        if ($value &lt; $this-&gt;minimum) {
            $this-&gt;_error(self::MSG_MINIMUM);
            return false;
        }

        if ($value &gt; $this-&gt;maximum) {
            $this-&gt;_error(self::MSG_MAXIMUM);
            return false;
        }

        return true;
    }
}
</pre>


        <div class="example-contents"><p>
            The public properties <var class="varname">$minimum</var> and <var class="varname">$maximum</var> have
            been established to provide the minimum and maximum boundaries, respectively, for a
            value to successfully validate. The class also defines two message variables that
            correspond to the public properties and allow <span class="property">min</span> and
            <span class="property">max</span> to be used in message templates as magic parameters, just as
            with <span class="property">value</span>.
        </p></div>

        <div class="example-contents"><p>
            Note that if any one of the validation checks in  <span class="methodname">isValid()</span>
            fails, an appropriate failure message is prepared, and the method immediately returns
            <b><tt>FALSE</tt></b>. These validation rules are therefore sequentially dependent.
            That is, if one test should fail, there is no need to test any subsequent validation
            rules. This need not be the case, however. The following example illustrates how to
            write a class having independent validation rules, where the validation object may
            return multiple reasons why a particular validation attempt failed.
        </p></div>
    </div>

    <div class="example" id="zend.validate.writing_validators.example.conditions.independent"><div class="info"><p><b>Example #3 Validation with Independent Conditions, Multiple Reasons for Failure</b></p></div>
        

        <div class="example-contents"><p>
            Consider writing a validation class for password strength enforcement - when a user is
            required to choose a password that meets certain criteria for helping secure user
            accounts. Let us assume that the password security criteria enforce that the password:
        </p></div>

        <ul class="itemizedlist">
            <li class="listitem"><p class="para">is at least 8 characters in length,</p></li>
            <li class="listitem"><p class="para">contains at least one uppercase letter,</p></li>
            <li class="listitem"><p class="para">contains at least one lowercase letter,</p></li>
            <li class="listitem"><p class="para">and contains at least one digit character.</p></li>
        </ul>

        <div class="example-contents"><p>
            The following class implements these validation criteria:
        </p></div>

        <pre class="programlisting brush: php">
class MyValid_PasswordStrength extends Zend_Validate_Abstract
{
    const LENGTH = &#039;length&#039;;
    const UPPER  = &#039;upper&#039;;
    const LOWER  = &#039;lower&#039;;
    const DIGIT  = &#039;digit&#039;;

    protected $_messageTemplates = array(
        self::LENGTH =&gt; &quot;&#039;%value%&#039; must be at least 8 characters in length&quot;,
        self::UPPER  =&gt; &quot;&#039;%value%&#039; must contain at least one uppercase letter&quot;,
        self::LOWER  =&gt; &quot;&#039;%value%&#039; must contain at least one lowercase letter&quot;,
        self::DIGIT  =&gt; &quot;&#039;%value%&#039; must contain at least one digit character&quot;
    );

    public function isValid($value)
    {
        $this-&gt;_setValue($value);

        $isValid = true;

        if (strlen($value) &lt; 8) {
            $this-&gt;_error(self::LENGTH);
            $isValid = false;
        }

        if (!preg_match(&#039;/[A-Z]/&#039;, $value)) {
            $this-&gt;_error(self::UPPER);
            $isValid = false;
        }

        if (!preg_match(&#039;/[a-z]/&#039;, $value)) {
            $this-&gt;_error(self::LOWER);
            $isValid = false;
        }

        if (!preg_match(&#039;/\d/&#039;, $value)) {
            $this-&gt;_error(self::DIGIT);
            $isValid = false;
        }

        return $isValid;
    }
}
</pre>


        <div class="example-contents"><p>
            Note that the four criteria tests in  <span class="methodname">isValid()</span> do not
            immediately return <b><tt>FALSE</tt></b>. This allows the validation class to
            provide <em class="emphasis">all</em> of the reasons that the input password failed to meet
            the validation requirements. if, for example, a user were to input the string &quot;#$%&quot; as a
            password,  <span class="methodname">isValid()</span> would cause all four validation failure
            messages to be returned by a subsequent call to  <span class="methodname">getMessages()</span>.
        </p></div>
    </div>
</div>
        <hr />

            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="zend.validate.validator_chains.html">Validator Chains</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="zend.validate.html">Zend_Validate</a></span><br />
                        <span class="home"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="zend.validate.messages.html">Validation Messages</a></div>
                    </td>
                </tr>
            </table>
</td>
        <td style="font-size: smaller;" width="15%"> <style type="text/css">
#leftbar {
	float: left;
	width: 186px;
	padding: 5px;
	font-size: smaller;
}
ul.toc {
	margin: 0px 5px 5px 5px;
	padding: 0px;
}
ul.toc li {
	font-size: 85%;
	margin: 1px 0 1px 1px;
	padding: 1px 0 1px 11px;
	list-style-type: none;
	background-repeat: no-repeat;
	background-position: center left;
}
ul.toc li.header {
	font-size: 115%;
	padding: 5px 0px 5px 11px;
	border-bottom: 1px solid #cccccc;
	margin-bottom: 5px;
}
ul.toc li.active {
	font-weight: bold;
}
ul.toc li a {
	text-decoration: none;
}
ul.toc li a:hover {
	text-decoration: underline;
}
</style>
 <ul class="toc">
  <li class="header home"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></li>
  <li class="header up"><a href="manual.html">Guia de Refer&ecirc;ncia do Programador</a></li>
  <li class="header up"><a href="reference.html">Refer&ecirc;ncia do Zend Framework</a></li>
  <li class="header up"><a href="zend.validate.html">Zend_Validate</a></li>
  <li><a href="zend.validate.introduction.html">Introduction</a></li>
  <li><a href="zend.validate.set.html">Standard Validation Classes</a></li>
  <li><a href="zend.validate.validator_chains.html">Validator Chains</a></li>
  <li class="active"><a href="zend.validate.writing_validators.html">Writing Validators</a></li>
  <li><a href="zend.validate.messages.html">Validation Messages</a></li>
 </ul>
 </td>
    </tr>
</table>

<script type="text/javascript" src="../js/shCore.js"></script>
<script type="text/javascript" src="../js/shAutoloader.js"></script>
<script type="text/javascript" src="../js/main.js"></script>

</body>
</html>